/******************************************************************************中
 * @brief: eth task
 * @Author: aple
 * @Date: 2022-12-14 12:37:50
 * @LastEditors: aple
 * @LastEditTime: 2022-12-14 12:41:45
 * @Verision: 1.0.0.0
 ******************************************************************************/
#include "framework.h"
#include "eth_task.h"
#include "drivers/mac/apm32f4xx_eth_driver.h"
#include "drivers/phy/lan8720_driver.h"

/*****************************************************************************
 * @brief   const
 *****************************************************************************/

/*****************************************************************************
 * @brief   function
 *****************************************************************************/
void eth_task(void const *argument);
static void client_handle(uint32_t socket_port);
int TCP_Start(void);
void cyclone_lib_init(void);

/*****************************************************************************
 * @brief Global variables
 *****************************************************************************/
DhcpClientSettings dhcpClientSettings;
DhcpClientContext dhcpClientContext;
SlaacSettings slaacSettings;
SlaacContext slaacContext;
uint32_t mac_ok = 0;
QWORD_TT ipv4_val;

/*****************************************************************************
 * @brief   task var
 *****************************************************************************/
osThreadDef(eth_task, osPriorityHigh, 1, 0x400);	
void eth_task_creat(void)
{
	os_obj.tid_eth = osThreadCreate(osThread(eth_task), NULL);
}
obj_init_app(eth_task_creat);

/*******************************************************************************
 * @brief: usb task
 * @param argument
 * @return {*}
 ******************************************************************************/
void tn_task(void const *argument)
{
	volatile const char *arg = argument;
	UUV8 cnt = 0;
	
	while(1)
	{
		osDelay(1);
		cnt++;
	}
}
extern const OsTaskParameters OS_TASK_DEFAULT_PARAMS;
void eth_task(void const *argument)
{
	osDelay(1000);
	/*
	int cnt = 10;
	while(cnt--)
	{
		char buff[16];
		sprintf(buff, "%d", cnt);
		volatile OsTaskId id1 = osCreateTask("tns", (OsTaskCode)tn_task, buff, &OS_TASK_DEFAULT_PARAMS);
		volatile OsTaskId id2 = osCreateTask("tns", (OsTaskCode)tn_task, buff, &OS_TASK_DEFAULT_PARAMS);
		osDelay(500);
		osDeleteTask(id1);
		osDeleteTask(id2);
		osDelay(100);
	}
	*/
	cyclone_lib_init();
	
	while (1)
	{
		if(!mac_ok)
		{
			osDelay(1);
			TCP_Start();
		}
		else
		{
			osDelay(100);
		}
	}
}

/*******************************************************************************
 * @brief: server app data
 ******************************************************************************/


/*******************************************************************************
 * @brief: server thread
 * @param void
 * @return {*}
 ******************************************************************************/
int TCP_Start(void)
{
#if (IPV4_SUPPORT == ENABLED)
	Ipv4Addr ipv4Addr;
#endif
	
	// 网络接口
	NetInterface *interface = &netInterface[0];

#if (IPV4_SUPPORT == ENABLED)
	// 获取IPV4地址
	ipv4GetHostAddr(interface, &ipv4Addr);
	if(!ipv4Addr)
	{
		return 0;
	}
#endif
	
	ipv4_val.uval = ipv4Addr;
	
	mac_ok = 1;
	
	emb_server_init();
	
	eth_app_server_init();
	
	etcp_server_init();
	
	etcp_client_init();
	
	mb_client_init();
	
	return 0;
}

/*******************************************************************************
 * @brief: cyclone init
 * @param void
 * @return {*}
 ******************************************************************************/
void cyclone_lib_init(void)
{
	volatile error_t error;
	NetInterface *interface;
	MacAddr macAddr;
	
	//TCP/IP stack initialization
	error = netInit();
	//Any error to report?
	if(error)
	{
		//TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");
	}
	
	//Configure the first Ethernet interface
	interface = &netInterface[0];

	//Set interface name
	netSetInterfaceName(interface, "eth0");
	//Set host name
	netSetHostname(interface, "MBClientDemo");
	//Select the relevant network adapter
	netSetDriver(interface, &apm32f4xxEthDriver);
	netSetPhyDriver(interface, &lan8720PhyDriver);
	//netSetPhyDriver(interface, &lan8720PhyDriver);
	//Set host MAC address
	macStringToAddr(APP_MAC_ADDR, &macAddr);
	netSetMacAddr(interface, &macAddr);

	//Initialize network interface
	error = netConfigInterface(interface);
	//Any error to report?
	if(error)
	{
		//Debug message
		//TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);
	}

#if (IPV4_SUPPORT == ENABLED)
#if (APP_USE_DHCP == ENABLED)
	//Get default settings
	dhcpClientGetDefaultSettings(&dhcpClientSettings);
	//Set the network interface to be configured by DHCP
	dhcpClientSettings.interface = interface;
	//Disable rapid commit option
	dhcpClientSettings.rapidCommit = FALSE;

	//DHCP client initialization
	error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings);
	//Failed to initialize DHCP client?
	if(error)
	{
		//Debug message
		//TRACE_ERROR("Failed to initialize DHCP client!\r\n");
	}

	//Start DHCP client
	error = dhcpClientStart(&dhcpClientContext);
	//Failed to start DHCP client?
	if(error)
	{
		//Debug message
		//TRACE_ERROR("Failed to start DHCP client!\r\n");
	}
#else
	//Set IPv4 host address
	ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr);
	ipv4SetHostAddr(interface, ipv4Addr);

	//Set subnet mask
	ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr);
	ipv4SetSubnetMask(interface, ipv4Addr);

	//Set default gateway
	ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr);
	ipv4SetDefaultGateway(interface, ipv4Addr);

	//Set primary and secondary DNS servers
	ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr);
	ipv4SetDnsServer(interface, 0, ipv4Addr);
	ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr);
	ipv4SetDnsServer(interface, 1, ipv4Addr);
#endif
#endif

#if (IPV6_SUPPORT == ENABLED)
#if (APP_USE_SLAAC == ENABLED)
	//Get default settings
	slaacGetDefaultSettings(&slaacSettings);
	//Set the network interface to be configured
	slaacSettings.interface = interface;

	//SLAAC initialization
	error = slaacInit(&slaacContext, &slaacSettings);
	//Failed to initialize SLAAC?
	if(error)
	{
		//Debug message
		//TRACE_ERROR("Failed to initialize SLAAC!\r\n");
	}

	//Start IPv6 address autoconfiguration process
	error = slaacStart(&slaacContext);
	//Failed to start SLAAC process?
	if(error)
	{
		//Debug message
		//TRACE_ERROR("Failed to start SLAAC!\r\n");
	}
#else
	//Set link-local address
	ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr);
	ipv6SetLinkLocalAddr(interface, &ipv6Addr);

	//Set IPv6 prefix
	ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr);
	ipv6SetPrefix(interface, 0, &ipv6Addr, APP_IPV6_PREFIX_LENGTH);

	//Set global address
	ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr);
	ipv6SetGlobalAddr(interface, 0, &ipv6Addr);

	//Set default router
	ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr);
	ipv6SetDefaultRouter(interface, 0, &ipv6Addr);

	//Set primary and secondary DNS servers
	ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr);
	ipv6SetDnsServer(interface, 0, &ipv6Addr);
	ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr);
	ipv6SetDnsServer(interface, 1, &ipv6Addr);
#endif
#endif
}

